package org.example.redpacket.service.impl;

import org.example.redpacket.common.exception.ActivityEmptyException;
import org.example.redpacket.common.exception.AlreadyInsertException;
import org.example.redpacket.common.exception.InsertOrUpdateException;
import org.example.redpacket.common.exception.NonUserException;
import org.example.redpacket.dao.UserRedPacketDetailMapper;
import org.example.redpacket.model.dto.RedPacketDetailPageQryDTO;
import org.example.redpacket.model.dto.UserRedPacketDetailDTO;
import org.example.redpacket.model.entity.UserRedPacketDetailEntity;
import org.example.redpacket.model.po.ActivityPO;
import org.example.redpacket.model.po.UserRedPacketDetailPO;
import org.example.redpacket.model.vo.RedPacketDetailPageRspVO;
import org.example.redpacket.service.ActivityService;
import org.example.redpacket.service.UserRedPacketDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户使用红包 接口实现类
 *
 * @author: hero生仔
 */
@Service
public class UserRedPacketDetailServiceImpl implements UserRedPacketDetailService {

    @Autowired
    private UserRedPacketDetailMapper userRedPacketDetailMapper;
    @Autowired
    private ActivityService activityService;


    @Override
    public Integer insertUserRedPacketDetail(UserRedPacketDetailEntity userRedPacketDetailEntity) {
        UserRedPacketDetailPO userRedPacketDetailPO = UserRedPacketDetailPO.builder()
                .userId(userRedPacketDetailEntity.getUserId())
                .activityId(userRedPacketDetailEntity.getActivityId())
                .redPacketId(userRedPacketDetailEntity.getRedPacketId())
                .receivedAmount(userRedPacketDetailEntity.getReceivedAmount())
                .useStatus(userRedPacketDetailEntity.getUseStatus())
                .build();
        Integer insertNum;
        try {
            insertNum = userRedPacketDetailMapper.insertUserRedPacketDetail(userRedPacketDetailPO);
        } catch (Exception e) {
            throw new AlreadyInsertException(e.getLocalizedMessage(), e);
        }
        return insertNum;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, noRollbackFor = {NonUserException.class})
    public String batchUpdateRedPacketDetail(UserRedPacketDetailDTO userRedPacketDetailDTO) {
        List<UserRedPacketDetailPO> result = Collections.synchronizedList(new ArrayList<>());
        // 查询用户领取红包详情信息
        List<UserRedPacketDetailPO> redPacketDetailPOList = userRedPacketDetailMapper.queryRedPacketDetail(userRedPacketDetailDTO.getUserId());
        if (redPacketDetailPOList.isEmpty()) {
            throw new NonUserException("用户不存在");
        }
        // 如果可用红包小于请求的红包个数，则使用那些没用过的红包即可
        else if (redPacketDetailPOList.size() < userRedPacketDetailDTO.getRedPacketList().size()) {
            // 筛选出没用过的红包
            List<String> redPacketList = redPacketDetailPOList.stream()
                    .map(UserRedPacketDetailPO::getRedPacketId)
                    .filter(redPacketId ->
                            userRedPacketDetailDTO.getRedPacketList().stream().anyMatch(rpId -> rpId.equals(redPacketId)))
                    .collect(Collectors.toList());

            updateRedPacketDetail(userRedPacketDetailDTO, redPacketList, result);
        } else {
            // 这里红包id保证是存在的
            updateRedPacketDetail(userRedPacketDetailDTO, userRedPacketDetailDTO.getRedPacketList(), result);
        }
        return "SUCCESS";
    }


    public void updateRedPacketDetail(UserRedPacketDetailDTO userRedPacketDetailDTO, List<String> redPacketList, List<UserRedPacketDetailPO> result) {
        for (String redPacketId : redPacketList) {
            UserRedPacketDetailPO userRedPacketDetailPO = UserRedPacketDetailPO.builder()
                    .useStatus(1)
                    .redPacketId(redPacketId)
                    .userId(userRedPacketDetailDTO.getUserId())
                    .build();
            result.add(userRedPacketDetailPO);
        }
        try {
            Integer count = userRedPacketDetailMapper.batchUpdateRedPacketDetail(result);
            count = Optional.ofNullable(count).orElse(0);
            if (count == 0 || count != result.size()) {
                throw new InsertOrUpdateException("更新用户明细表记录异常");
            }
        } catch (Exception e) {
            throw new InsertOrUpdateException("更新用户明细表记录异常");
        }
    }

    @Override
    public List<RedPacketDetailPageRspVO> qryRedPacketDetailByPage(RedPacketDetailPageQryDTO redPacketDetailPageQryDTO) {
        int pageSize = redPacketDetailPageQryDTO.getPageSize();
        Integer key = redPacketDetailPageQryDTO.getKey();
        String activityId = redPacketDetailPageQryDTO.getActivityId();

        // 查看该活动是否还上线
        ActivityPO activityPO = activityService.qryActivity(activityId);
        if (activityPO == null) {
            throw new ActivityEmptyException("活动" + activityId + "还没上线");
        }

        List<UserRedPacketDetailPO> redPacketDetailPOList = userRedPacketDetailMapper.queryRedPacketByPageSize(activityId, key, pageSize);
        if (redPacketDetailPOList == null || redPacketDetailPOList.isEmpty()) {
            return new ArrayList<>();
        }
        // 组装出参并返回
        return redPacketDetailPOList.stream().map(po -> RedPacketDetailPageRspVO.builder()
                .id(po.getId())
                .userId(po.getUserId())
                .activityId(po.getActivityId())
                .amount(po.getReceivedAmount())
                .orderType(po.getUseStatus())
                .redPacketId(po.getRedPacketId())
                .build()).collect(Collectors.toList());
    }
}
